package jmine.tec.security.impl.web.pages.grupousuario;

import java.util.ArrayList;
import java.util.List;

import jmine.tec.web.wicket.component.button.ActionAjaxButton;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.ListMultipleChoice;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.hibernate.criterion.Order;

import bancosys.tec.security.annotation.Secure;
import bancosys.tec.security.impl.SecurityController;
import bancosys.tec.security.impl.dao.ChineseWallCredentialDAO;
import bancosys.tec.security.impl.domain.ChineseWallCredential;
import bancosys.tec.security.impl.domain.Group;

/**
 * Tela de cadastro {@link ChineseWallCredential} para o {@link Group}.
 * 
 * @author diego.ferreira
 * @created Jan 10, 2011
 */
@Secure
public class CadastroGroupChineseWall extends Panel {

    @SpringBean(name = "securityController")
    private SecurityController securityController;

    private static final String REMOVE = "REMOVE";

    private static final String ADD = "ADD";

    private Group group;

    private ListMultipleChoice<ChineseWallCredential> credentials;

    private ListMultipleChoice<ChineseWallCredential> credentialsSelecionadas;

    private List<ChineseWallCredential> credentialsModelList = new ArrayList<ChineseWallCredential>();

    private List<ChineseWallCredential> credentialsSelecionadasModelList = new ArrayList<ChineseWallCredential>();

    private List<ChineseWallCredential> credentialsList = new ArrayList<ChineseWallCredential>();

    private List<ChineseWallCredential> credentialsSelecionadasList = new ArrayList<ChineseWallCredential>();

    /**
     * Construtor
     * 
     * @param id panel id.
     * @param group {@link Group}
     */
    public CadastroGroupChineseWall(String id, Group group) {
        super(id);
        this.group = group;
        this.initList();
        this.generateComponents();
    }

    /**
     * Inicializa as listas apresentadas na tela.
     */
    private void initList() {
        if (!this.group.getCredentials().isEmpty()) {
            for (ChineseWallCredential credential : this.getCredentialDAO().findAll(Order.asc("mnemonico"))) {
                if (this.group.getCredentials().contains(credential)) {
                    this.credentialsSelecionadasModelList.add(credential);
                } else {
                    this.credentialsModelList.add(credential);
                }
            }
        }

        /**
         * Caso o usuário possua outras credentials e tenha todas as ChineseWallCredential associadas
         */
        if (this.credentialsModelList.isEmpty() && this.credentialsSelecionadasModelList.isEmpty()) {
            this.credentialsModelList = this.getCredentialDAO().findAll(Order.asc("mnemonico"));
        }

        this.credentialsList = new ArrayList<ChineseWallCredential>(this.credentialsModelList);
        this.credentialsSelecionadasList = new ArrayList<ChineseWallCredential>(this.credentialsSelecionadasModelList);
    }

    /**
     * Gera os componentes utilizados em tela.
     */
    private void generateComponents() {
        this.add(new FeedbackPanel("feedback").setOutputMarkupId(true));
        this.credentials =
                new ListMultipleChoice<ChineseWallCredential>("credentials", new PropertyModel<List<ChineseWallCredential>>(this,
                        "credentialsModelList"), this.credentialsModelList) {
                    @Override
                    protected void appendOptionHtml(AppendingStringBuffer buffer, ChineseWallCredential choice, int index, String selected) {
                        super.appendOptionHtml(buffer, choice, index, null);
                    }
                };
        this.credentials.setOutputMarkupId(true);
        this.add(this.credentials);
        this.credentialsSelecionadas =
                new ListMultipleChoice<ChineseWallCredential>("credentialsSelecionadas", new PropertyModel<List<ChineseWallCredential>>(
                        this, "credentialsSelecionadasModelList"), this.credentialsSelecionadasModelList) {
                    @Override
                    protected void appendOptionHtml(AppendingStringBuffer buffer, ChineseWallCredential choice, int index, String selected) {
                        super.appendOptionHtml(buffer, choice, index, null);
                    }
                };
        this.credentialsSelecionadas.setOutputMarkupId(true);
        this.add(this.credentialsSelecionadas);

        this.add(this.credentialsSelecionadas);
        AjaxButton btnAdicionar = new ActionAjaxButton("btnAdicionar") {

            @Override
            public void onAction(AjaxRequestTarget target, Form formulario) {
                CadastroGroupChineseWall.this.update(target, CadastroGroupChineseWall.this.credentialsModelList, ADD);

            }

        };
        this.add(btnAdicionar);

        AjaxButton btnRemover = new ActionAjaxButton("btnRemover") {
            @Override
            public void onAction(AjaxRequestTarget target, Form formulario) {
                CadastroGroupChineseWall.this.update(target, CadastroGroupChineseWall.this.credentialsSelecionadasModelList, REMOVE);
            }
        };
        this.add(btnRemover);
    }

    /**
     * Atualiza as listas.
     * 
     * @param target o {@link AjaxRequestTarget}.
     * @param selections os {@link ChineseWallCredential} selecionados.
     * @param action ação a ser executada.
     */
    private void update(AjaxRequestTarget target, List<ChineseWallCredential> selections, String action) {

        for (ChineseWallCredential credentialSelect : selections) {

            if (action.equals(ADD)) {
                if (!this.credentialsSelecionadasList.contains(credentialSelect)) {
                    this.credentialsList.remove(credentialSelect);
                    this.credentialsSelecionadasList.add(credentialSelect);
                    this.group.addCredential(credentialSelect);
                }
            } else {
                if (!this.credentialsList.contains(credentialSelect)) {
                    this.credentialsSelecionadasList.remove(credentialSelect);
                    this.group.getCredentials().remove(credentialSelect);
                    this.credentialsList.add(credentialSelect);
                }
            }
        }

        this.credentialsModelList = new ArrayList<ChineseWallCredential>(this.credentialsList);
        this.credentialsSelecionadasModelList = new ArrayList<ChineseWallCredential>(this.credentialsSelecionadasList);

        this.credentialsSelecionadas.setChoices(this.credentialsSelecionadasModelList);
        this.credentials.setChoices(this.credentialsModelList);
        target.addComponent(this.credentials);
        target.addComponent(this.credentialsSelecionadas);
    }

    /**
     * @return {@link ChineseWallCredentialDAO}
     */
    private ChineseWallCredentialDAO getCredentialDAO() {
        return this.securityController.getDAOFactory().getDAOByClass(ChineseWallCredentialDAO.class);
    }
}
